package com.lsa.expression.visitor;

import java.util.List;

import com.lsa.expression.tree.ExprNode;
import com.lsa.expression.tree.FactorNode;
import com.lsa.expression.tree.Node;
import com.lsa.expression.tree.OperatorNode;
import com.lsa.expression.tree.TermNode;

public class EvalWalker
{
    public static int walk(Node node)
    {
        int result = 0;
        
        if (node instanceof ExprNode)
        {
            ExprNode expr = (ExprNode)node;  
            result = walk((Node)expr.getSubNodes().get(0));
            String oper = "";
            for( int i = 1; i < expr.getSubNodes().size(); i++ )
            {               
                if ( (i % 2) == 1)
                {
                    oper = ((OperatorNode)expr.getSubNodes().get(i)).getOperator();
                }
                else
                {
                    int operand = walk((Node)expr.getSubNodes().get(i));
                    if ("+".equals(oper))
                    {
                        result += operand;
                    }
                    else if ("-".equals(oper))
                    {
                        result -= operand;
                    }
                }
            }
        }
        else if (node instanceof TermNode)
        {
            TermNode term = (TermNode)node;  
            
            int previous = walk((Node)term.getSubNodes().get(0));
            List subNodes = term.getSubNodes();
            if (subNodes.size() > 1)
            {
                String oper = "";
                for( int i = 1; i < subNodes.size(); i++ )
                {               
                    if ( (i % 2) == 1)
                    {
                        oper = ((OperatorNode)subNodes.get(i)).getOperator();
                    }
                    else
                    {
                        int operand = walk((Node)subNodes.get(i));
                        if ("*".equals(oper))
                        {
                            result += previous * operand;
                        }
                        else if ("/".equals(oper))
                        {
                            result += previous / operand;
                        }
                        
                        previous = operand;
                    }
                }
            }
            else
            {
                result = previous;
            }
        }
        else if (node instanceof OperatorNode)
        {
        }
        else if (node instanceof FactorNode)
        {
            FactorNode factorNode = (FactorNode)node;
            if (node.getSubNodes().isEmpty())
            {
                result = Integer.parseInt(factorNode.getData());
            }
            else
            {
                result = walk((Node)node.getSubNodes().get(0));
            }
        }
        
        return result;
    }
}
